#include "StdAfx.h"
//#include "cdbclass.h" // precompiled header
#include "CCSVReader.h"
//#include "CDBRace.h" // precompiled header
//#include "CDBStyleLine.h" // precompiled header
//#include "CDBSpellLine.h" // precompiled header



CDBClass::CDBClass(void)
{
	mpc_races = NULL;
	mpc_styles = NULL;
	mpc_spells = NULL;
}

CDBClass::~CDBClass(void)
{
}



CDBClass::struct_class &CDBClass::struct_class::operator=( CDBClass::struct_class const &rs_data )
{
	id = rs_data.id;
	base_class = rs_data.base_class;
	n_realm = rs_data.n_realm;
	name = rs_data.name;
	mora_id = rs_data.mora_id;
	magie = rs_data.magie;
	stat_primary = rs_data.stat_primary;
	stat_secondary = rs_data.stat_secondary;
	stat_tertiary = rs_data.stat_tertiary;
	skillfactor = rs_data.skillfactor;
	only_female = rs_data.only_female;
	is_list_caster = rs_data.is_list_caster;


	base_hps = rs_data.base_hps;
	hpcon_factor = rs_data.hpcon_factor;
	base_wf = rs_data.base_wf;
	wf_factor = rs_data.wf_factor;
	base_wf_b = rs_data.base_wf_b;
	wf_factor_b = rs_data.wf_factor_b;

	races.RemoveAll();
	for (int t=0;t<rs_data.races.GetCount();t++)
		races.Add((int)rs_data.races[t]);

	styles.RemoveAll();
	for (int t=0;t<rs_data.styles.GetCount();t++)
		styles.Add((int)rs_data.styles[t]);

	spells.RemoveAll();
	for (int t=0;t<rs_data.spells.GetCount();t++)
		spells.Add((int)rs_data.spells[t]);

	styles_auto.RemoveAll();
	for (int t=0;t<rs_data.styles_auto.GetCount();t++)
		styles_auto.Add((int)rs_data.styles_auto[t]);

	spells_auto.RemoveAll();
	for (int t=0;t<rs_data.spells_auto.GetCount();t++)
		spells_auto.Add((int)rs_data.spells_auto[t]);

	return *this;
}


CDBClass::struct_class::struct_class()
{
	id = -1;
	name.Empty();
	n_realm = -1;
	base_class.Empty();
	magie=-1;
	stat_primary =-1;
	stat_secondary =-1;
	stat_tertiary =-1;
	skillfactor = 1.0f;
	is_list_caster = false;

	base_hps = 0;
	hpcon_factor = 0.0f;
	base_wf = 0;
	wf_factor = 0.0f;
	base_wf_b = 0;
	wf_factor_b = 0.0f;

	races.RemoveAll();
	styles.RemoveAll();
	spells.RemoveAll();
	styles_auto.RemoveAll();
	spells_auto.RemoveAll();
}



int	CDBClass::GetStatID(const CString& stat_name)
{
	if ( stat_name.Left(3).CompareNoCase(_T("str"))==0) return 0;
	if ( stat_name.Left(3).CompareNoCase(_T("con"))==0) return 1;
	if ( stat_name.Left(3).CompareNoCase(_T("dex"))==0) return 2;
	if ( stat_name.Left(3).CompareNoCase(_T("qui"))==0) return 3;
	if ( stat_name.Left(3).CompareNoCase(_T("int"))==0) return 4;
	if ( stat_name.Left(3).CompareNoCase(_T("pie"))==0) return 5;
	if ( stat_name.Left(3).CompareNoCase(_T("emp"))==0) return 6;
	if ( stat_name.Left(3).CompareNoCase(_T("cha"))==0) return 7;

	ASSERT(false); // unknown stat_name
	return -1;
}


void	CDBClass::DeleteContents()
{
	mdb_classes.RemoveAll();
}


int CDBClass::ReadDB(const CString& path, CDBRace*pc_races, CDBStyleLine*pc_styles, CDBSpellLine*pc_spells)
{
	CString temp;

	mpc_races = pc_races;
	mpc_styles = pc_styles;
	mpc_spells = pc_spells;


	// Open
	// CTextReader inf;
	// bool res = inf.Open(_T("classes.dat"));
	CCSVReader inf;
	bool res = inf.Open(path+_T("classes.csv"));
	ASSERT(res);	// can't open "classes.dat"
	if (!res)	return ERR_CANT_OPEN_TABLE;


	// Read File
	do
	{

			struct_class new_class;

			new_class.name = inf.ReadString();

			CString realm = inf.ReadString();
			if (realm.CompareNoCase(_T("albion"))==0)	new_class.n_realm = 0;	else
			if (realm.CompareNoCase(_T("hibernia"))==0)	new_class.n_realm = 1;	else
			if (realm.CompareNoCase(_T("midgard"))==0)	new_class.n_realm = 2;	else
				{	ASSERT(false); /* illegal REALM-String*/
					return ERR_ILLEGAL_REALM;
				}

			new_class.base_class = inf.ReadString();
			new_class.mora_id = inf.ReadString();
			new_class.is_list_caster = 0!=inf.ReadInt();
			
			temp = inf.ReadString();
			if (temp != "0")		new_class.magie = GetStatID(temp);
			else					new_class.magie = -1;

			new_class.stat_primary = GetStatID(inf.ReadString());
			new_class.stat_secondary = GetStatID(inf.ReadString());
			new_class.stat_tertiary = GetStatID(inf.ReadString());

			new_class.skillfactor = inf.ReadFloat();

			new_class.base_hps = inf.ReadInt();
			new_class.hpcon_factor = inf.ReadFloat();
			new_class.base_wf = inf.ReadInt();
			new_class.wf_factor = inf.ReadFloat();
			new_class.base_wf_b = inf.ReadInt();
			new_class.wf_factor_b = inf.ReadFloat();

			// races
			int nof_races = inf.ReadInt();
			for (int run=0;run<nof_races;run++)
			{
				int n = pc_races->FindRaceID(inf.ReadString());
				ASSERT(n!=-1); // Race not found
				if (n==-1)	return ERR_ILLEGAL_RACE;
				new_class.races.Add(n);
			}

			// styleline
			int nof_styles = inf.ReadInt();
			for (int run=0;run<nof_styles;run++)
			{
				bool b_auto = false;
				CString str = inf.ReadString();
				if (str.Find('*')!=-1) {b_auto = true; str.Replace(_T("*"),_T(""));}

				int n = pc_styles->GetStyleLineID(_tstoi(str));
				ASSERT(n!=-1); // StyleLine not found
				if (n==-1)	return ERR_ILLEGAL_STYLELINE;
				new_class.styles.Add(n);
				if (b_auto) new_class.styles_auto.Add(n);
			}

			int nof_spells = inf.ReadInt();
			for (int run=0;run<nof_spells;run++)
			{
				bool b_auto = false;
				CString str = inf.ReadString();
				if (str.Find('*')!=-1) {b_auto = true; str.Replace(_T("*"),_T(""));}

				int n = pc_spells->GetSpellLineID(_tstoi(str));
				ASSERT(n!=-1); // SpellLineID not found
				if (n==-1)	return ERR_ILLEGAL_SPELLLINE;
				new_class.spells.Add(n);
				if (b_auto) new_class.spells_auto.Add(n);
			}


			new_class.only_female = 0!=inf.ReadInt();;

			mdb_classes.Add(new_class);

	} while (inf.NextLine());

	return ERR_NO_ERROR;
}


void CDBClass::GetRaces(CStringArray &output, int mn_selected_class)
{
	ASSERT(mpc_races); // not propertly initialized
	ASSERT(mn_selected_class>=0 && mn_selected_class<mdb_classes.GetCount()); // illegal class ID

	for (int run=0;run<mdb_classes[mn_selected_class].races.GetCount();run++)
	{
		output.Add(mpc_races->GetRaceName(mdb_classes[mn_selected_class].races[run]));
	}
}

void CDBClass::GetClasses(CStringArray &output, int mn_selected_realm)
{
	for (int run=0;run<mdb_classes.GetCount();run++)
		if (mn_selected_realm == -1 || mdb_classes[run].n_realm == mn_selected_realm)
		{
			output.Add(mdb_classes[run].name);
		}
}


int	CDBClass::GetClassID(const CString& classname)
{
	for (int run=0;run<mdb_classes.GetCount();run++)
		if (mdb_classes[run].name.CompareNoCase(classname)==0) return run;

	return -1;
}


int	CDBClass::FindMoraClass(LPCTSTR pc_str)
{
	for (int run=0;run<mdb_classes.GetCount();run++)
		if (mdb_classes[run].mora_id.Compare(pc_str)==0) return run;

	return -1;
}

LPCTSTR	CDBClass::GetMoraClassName(int id)
{
	return mdb_classes[id].mora_id;
}


CString	CDBClass::GetName(int id)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID
	return mdb_classes[id].name;
}

CString	CDBClass::GetBaseClass(int id)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID
	return mdb_classes[id].base_class;
}


int	CDBClass::GetRealm(int id)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID
	
	return mdb_classes[id].n_realm;
}

//////////////////////////////////////////////////////////////////////////
bool	CDBClass::OnlyFemale(int id)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID
	
	return mdb_classes[id].only_female;
}


//////////////////////////////////////////////////////////////////////////
bool	CDBClass::IsListCaster(int id)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	return mdb_classes[id].is_list_caster;
}


//////////////////////////////////////////////////////////////////////////
bool CDBClass::IsValidRace(int id, int race)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	for (int run=0;run<mdb_classes[id].races.GetCount();run++)
	{
		if (mdb_classes[id].races[run] == race) return true;
	}

	return false;
}


bool	CDBClass::IsValidStyleLineID(int id, int styleid)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	for (int run=0;run<mdb_classes[id].styles.GetCount();run++)
	{
		if (mdb_classes[id].styles[run] == styleid) return true;
	}

	return false;
}





int CDBClass::GetStatPrimary(int id)
{
	return mdb_classes[id].stat_primary;
}

int CDBClass::GetStatSecondary(int id)
{
	return mdb_classes[id].stat_secondary;
}

int CDBClass::GetStatTertiary(int id)
{
	return mdb_classes[id].stat_tertiary;
}

int	CDBClass::GetStatMagic(int id)
{
	return mdb_classes[id].magie;
}

float	CDBClass::GetSkillFactor(int id)
{
	return mdb_classes[id].skillfactor;
}

void	CDBClass::GetHPModifiers(int id, int &basehps, float& confactor)
{
	basehps = mdb_classes[id].base_hps;
	confactor = mdb_classes[id].hpcon_factor;
}

void	CDBClass::GetWFModifiers(int id, int &basewfs, float& wffactor, int &basewfs_b, float& wffactor_b)
{
	basewfs = mdb_classes[id].base_wf;
	wffactor = mdb_classes[id].wf_factor;

	basewfs_b = mdb_classes[id].base_wf_b;
	wffactor_b = mdb_classes[id].wf_factor_b;

}

void	CDBClass::GetStyleLines(int id,CArray <int,int&>&res)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	res.RemoveAll();
	for (int run=0;run<mdb_classes[id].styles.GetCount();run++)
	{	
		res.Add(mdb_classes[id].styles[run]);
	}
}



int	CDBClass::GetStyleLineID(int id, const CString&  styleline)
{
	ASSERT(mpc_styles != NULL);
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	for (int run=0;run<mdb_classes[id].styles.GetCount();run++)
	{	
		if (mpc_styles->GetName(mdb_classes[id].styles[run]).CompareNoCase(styleline)==0)
			return mdb_classes[id].styles[run];
	}

	return -1;
}

int	CDBClass::GetSpellLineID(int id, const CString&  spellline)
{
	ASSERT(mpc_spells != NULL);
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	for (int run=0;run<mdb_classes[id].spells.GetCount();run++)
	{	
		if (mpc_spells->GetNameBase(mdb_classes[id].spells[run]).CompareNoCase(spellline)==0)
			return mdb_classes[id].spells[run];
	}

	return -1;
}





void	CDBClass::GetSpellLines(int id,CArray <int,int&>&res)
{
	ASSERT(id>=0 && id<mdb_classes.GetCount()); // illegal class ID

	res.RemoveAll();
	for (int run=0;run<mdb_classes[id].spells.GetCount();run++)
	{
		res.Add(mdb_classes[id].spells[run]);
	}
}


bool	CDBClass::IsAutoStyle(int id,int styleid)
{
	for (int n=0;n<mdb_classes[id].styles_auto.GetCount();n++)
		if (mdb_classes[id].styles_auto[n]==styleid) return true;
	return false;
}

bool	CDBClass::IsAutoSpell(int id,int spellid)
{
	for (int n=0;n<mdb_classes[id].spells_auto.GetCount();n++)
		if (mdb_classes[id].spells_auto[n]==spellid) return true;
	return false;
}



void	CDBClass::InsertSpellLine(int id,  int spellid)
{
	for (int n=0;n<mdb_classes[id].spells.GetCount();n++)
		if (mdb_classes[id].spells[n]==spellid) return;

	mdb_classes[id].spells.Add(spellid);
}
